/***************************************************************************
 *   Copyright 2005-2009 Last.fm Ltd.                                      *
 *   Portions contributed by Casey Link, Lukasz Wisniewski,                *
 *   Mike Jennings, and Michael Novak Jr.                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/
package fm.last.android;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;

public class LastFm extends Activity {
	public static final String PREFS = "LoginPrefs";
	private EditText mPassField;
	private EditText mUserField;
	private Button mLoginButton;
	private Button mSignupButton;

	String authInfo;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle icicle) {

		super.onCreate(icicle);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		SharedPreferences settings = getSharedPreferences(PREFS, 0);
		String user = settings.getString("lastfm_user", "");
		String session_key = settings.getString("lastfm_session_key", "");
		String pass;
		
		if(Integer.decode(Build.VERSION.SDK) >= 6) {
			if(!AccountAuthenticatorService.hasLastfmAccount(this)) {
				session_key = "";
				AccountDemo.getInstance().logout();
			}
		}
		
		if (!user.equals("") && !session_key.equals("")) {
			if (getIntent().getAction() != null && getIntent().getAction().equals("fm.last.android.sync.LOGIN")) {
				Intent intent = getIntent();
				Bundle extras = intent.getExtras();
				if (extras != null) {
					try {
						AccountAuthenticatorService.addAccount(this, user, session_key, extras.getParcelable("accountAuthenticatorResponse"));
					} catch (Exception e) {
						Log.i("Last.fm", "Unable to add account");
					}
				}
			}
			finish();
			return;
		}
		setContentView(R.layout.login);
		mPassField = (EditText) findViewById(R.id.password);
		mUserField = (EditText) findViewById(R.id.username);
		if (!user.equals(""))
			mUserField.setText(user);
		mLoginButton = (Button) findViewById(R.id.sign_in_button);
		mSignupButton = (Button) findViewById(R.id.sign_up_button);
		mUserField.setNextFocusDownId(R.id.password);

		mPassField.setOnKeyListener(new View.OnKeyListener() {

			public boolean onKey(View v, int keyCode, KeyEvent event) {
				switch (event.getKeyCode()) {
				case KeyEvent.KEYCODE_ENTER:
					mLoginButton.setPressed(true);
					mLoginButton.performClick();
					return true;
				}
				return false;
			}
		});

		if (icicle != null) {
			user = icicle.getString("username");
			pass = icicle.getString("pass");
			if (user != null)
				mUserField.setText(user);

			if (pass != null)
				mPassField.setText(pass);
		}

		mLoginButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (mLoginTask != null)
					return;

				String user = mUserField.getText().toString();
				String password = mPassField.getText().toString();

				if (user.length() == 0 || password.length() == 0) {
					AccountDemo.getInstance().presentError(v.getContext(), getResources().getString(R.string.ERROR_MISSINGINFO_TITLE),
							getResources().getString(R.string.ERROR_MISSINGINFO));
					return;
				}

				mLoginTask = new LoginTask(v.getContext());
				mLoginTask.execute(user, password);
			}
		});

		mSignupButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Intent intent = new Intent(LastFm.this, SignUp.class);
				startActivityForResult(intent, 0);
			}
		});
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode != 0 || resultCode != RESULT_OK)
			return;

		mUserField.setText(data.getExtras().getString("username"));
		mPassField.setText(data.getExtras().getString("password"));
		mLoginButton.requestFocus();
		mLoginButton.performClick();
	}

	/**
	 * In a task because it can take a while, and Android has a tendency to
	 * panic and show the force quit/wait dialog quickly. And this blocks.
	 */
	private class LoginTask extends AsyncTaskEx<String, Void, Session> {
		Context context;
		ProgressDialog mDialog;

		Exception e;
		WSError wse;

		LoginTask(Context c) {
			this.context = c;
			mLoginButton.setEnabled(false);

			mDialog = ProgressDialog.show(c, "", getString(R.string.main_authenticating), true, false);
			mDialog.setCancelable(true);
		}

		@Override
		public Session doInBackground(String... params) {
			String user = params[0];
			String pass = params[1];

			try {
				return login(user, pass);
			} catch (WSError e) {
				e.printStackTrace();
				wse = e;
			} catch (Exception e) {
				e.printStackTrace();
				this.e = e;
			}

			return null;
		}

		Session login(String user, String pass) throws Exception, WSError {
			user = user.toLowerCase().trim();
			LastFmServer server = AndroidLastFmServerFactory.getServer();
			String md5Password = MD5.getInstance().hash(pass);
			String authToken = MD5.getInstance().hash(user + md5Password);
			Session session = server.getMobileSession(user, authToken);
			if (session == null)
				throw (new WSError("auth.getMobileSession", "auth failure", WSError.ERROR_AuthenticationFailed));
			if(Integer.decode(Build.VERSION.SDK) >= 6) {
				Parcelable authResponse = null;
				if(getIntent() != null && getIntent().getExtras() != null)
					authResponse = getIntent().getExtras().getParcelable("accountAuthenticatorResponse");
				AccountAuthenticatorService.addAccount(LastFm.this, user, pass, authResponse);
			}
			return session;
		}

		@Override
		public void onPostExecute(Session session) {
			mLoginButton.setEnabled(true);
			mLoginTask = null;

			if (session != null) {
				SharedPreferences.Editor editor = getSharedPreferences(PREFS, 0).edit();
				editor.putString("lastfm_user", session.getName());
				editor.putString("lastfm_session_key", session.getKey());
				editor.putString("lastfm_subscriber", session.getSubscriber());
				editor.putBoolean("remove_playlists", true);
				editor.putBoolean("remove_tags", true);
				editor.putBoolean("remove_loved", true);
				editor.commit();

				AccountDemo.getInstance().session = session;

				finish();
			} else if (wse != null) {
				AccountDemo.getInstance().presentError(context, wse);
			} else if (e != null && e.getMessage() != null) {
				AlertDialog.Builder d = new AlertDialog.Builder(LastFm.this);
				d.setIcon(android.R.drawable.ic_dialog_alert);
				d.setNeutralButton(getString(R.string.common_ok), new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
					}
				});
				if (e.getMessage().contains("code 403")) {
					d.setTitle(getResources().getString(R.string.ERROR_AUTH_TITLE));
					d.setMessage(getResources().getString(R.string.ERROR_AUTH));
					((EditText) findViewById(R.id.password)).setText("");
					d.setNegativeButton(getString(R.string.main_forgotpassword), new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton) {
							final Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://www.last.fm/settings/lostpassword"));
							startActivity(myIntent);
						}
					});
				} else {
					d.setTitle(getResources().getString(R.string.ERROR_SERVER_UNAVAILABLE_TITLE));
					d.setMessage(getResources().getString(R.string.ERROR_SERVER_UNAVAILABLE));
				}
				d.show();
			}

			if(mDialog.isShowing()) {
				try {
					mDialog.dismiss();
				} catch (Exception e) { //This occasionally fails
					e.printStackTrace();
				}
			}
		}
	}

	private LoginTask mLoginTask;
}
